package com.lkd.fliter;


import com.lkd.config.SkipAuthProperties;
import com.lkd.http.view.TokenObject;
import com.lkd.utils.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
@Slf4j
public class AuthFilter implements GlobalFilter {

    @Autowired
    private SkipAuthProperties props;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

//        获取请求对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
//        获取请求路径
        String path = request.getURI().getPath();
        log.info("path={}",path);
        List<String> urls = props.getUrls();
        if(!CollectionUtils.isEmpty(urls)) {
//        1、判断路径是否需要验证
            boolean b = urls.stream().anyMatch(url -> path.contains(url));
            if (b) {
                log.info("直接放行");
//            如果不需要验证，放行
                return chain.filter(exchange);
            }
        }
//        从请求头获取token
        String token = request.getHeaders().getFirst("Authorization");
//        判断是否有token
        if(StringUtils.isBlank(token)) {
            log.error("没有请求token,结束");
//             如果没有token，结束返回
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
//        2、验证token是否有效
        try {
            TokenObject tokenObject = JWTUtil.decode(token);
            JWTUtil.VerifyResult verifyResult = JWTUtil.verifyJwt(token, tokenObject);
            if(!verifyResult.isValidate()){
//              如果验证失败，结束返回
                log.error("token验证失败,结束");
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            log.info("tokenobject={}",tokenObject);
//       3、 把用户信息放入请求头，转发
            Integer userId = tokenObject.getUserId();
            Integer loginType = tokenObject.getLoginType();
            String mobile = tokenObject.getMobile();
//            重新生成请求对象
            ServerHttpRequest httpRequest = request.mutate()
                    .header("userId",userId.toString())
                    .header("loginType",loginType.toString())
                    .header("mobile",mobile)
                    .build();
//            修改exchange中的请求对象
            exchange.mutate().request(httpRequest);
        }catch (Exception e) {
//              如果验证失败，结束返回
            log.error("没有请求token验证失败,结束");
            e.printStackTrace();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
//          放行
        return chain.filter(exchange);
    }

}
